/*相似K线——股票详情页
*跳转和传参示例this.$router.push({path: '/stock', query: {stockName: '股票名称', stockCode: 'SH603939', similarNum: 100 ,upNum: 38, downNum: 62}
*stockName stockCode 必传
*similarNum  upNum  downNum    相似总数、上涨数、下跌数  （非必传）
*/
<template>
  <div id="stock-page" class="common-content g-bg" :class="{'isShare': isShare, 'error': isError}">
    <header-top :title="stockName + ' ' + stockCode" :operation="headOpera" :stock="market + stockCode" :page="'stock'" v-if="!isShare"></header-top>

    <template v-if="showTodaySimi">
      <div class="nodata">
        <img src="~assets/images/nodata_2x.png" class="nodata-img">
        <div class="nodata-text">今日未找到K线走势相似度最高的个股哦，去看看今日之最吧!</div>
      </div>
      <todaySimilar></todaySimilar>
      <div class="risk-remind">以上信息不作为任何投资意见 <span @click.stop="toWaring(2)">风险提示</span></div>
    </template>

    <div class="error" v-else-if="isError">
      <img src="~assets/images/error_2x.png" class="error-img">
      <div class="error-text">出错了，点击重试</div>
      <div class="error-btn" @click.stop="reFetchData">重试</div>
    </div>

    <template v-else>
      <div class="fixed-top">
        <top-bar :upNum="upNum" :downNum="downNum" :similarNum="similarNum" :stock="market + stockCode" :isShare="isShare"></top-bar>
        <div class="chart-note">
          <div><span>相似区间</span></div>
          <div><span @click.stop="toFuture">模拟走势 </span><i class="iconfont icon-wenhao" @click.stop="toFuture"></i></div>
        </div>
        <main-stock :mainStock="mainStock" :guessed="guessed" :stock="market + stockCode" :isShare="isShare" :page="'stock'"></main-stock>
      </div>
      <div class="main-blank"></div>
      <similar-list :simiList="simiList" :similarNum="similarNum" :stock="market + stockCode" :isShare="isShare" v-if="simiList.length>0"></similar-list>
      <div class="risk-remind">以上信息不作为任何投资意见 <span @click.stop="toWaring(2)">风险提示</span></div>
    </template>

    <down-load v-if="isShare" :page="'stock'"></down-load>
  </div>
</template>

<script>
  import Constant from '@/common/constant'
  import RemoteDAO from '@/common/RemoteDAO'
  import CommonUtil from '@/common/common.util'
  import HeaderTop from '@/components/common/HeaderTop'
  import DownLoad from '@/components/common/DownLoad'
  import MainStock from '@/components/stock/MainStock'
  import SimilarList from '@/components/stock/SimilarList'
  import TopBar from '@/components/stock/TopBar'
  import todaySimilar from '@/components/todaySimilar/index.vue'
  import jsonSKLine from '@/filters/jsonSKLine'
  import jquery from 'jquery'

  const TDAPP = window.TDAPP

  export default {
    name: 'Stock',
    data () {
      return {
        headOpera: [Constant.Operation.SHARE], // 头部操作按钮
        stockName: '--',
        stockCode: '--',
        market: '', // 市场标志
        marketCode: '1',
        mainStock: null, // 模板股票配置
        simiList: [], // 相似股票配置
        upNum: 0,
        downNum: 0,
        similarNum: 0,
        patClosePriceLast: 0, // 模板股票最后一天收盘价
        guessed: false, // 是否已计算好模拟走势图的配置
        showTodaySimi: false, // 是否显示的是今日最相似画面
        isError: false, // 是否报错
        isShare: false // 是否为分享状态
      }
    },
    watch: {
      '$route' (to, from) {
        if (to.path === '/stock' && from.path === '/stock') {
          this.init()
        }
      }
    },
    created () {
      // this.init()
    },
    activated () {
      if (this.$store.state.rePage) {
        this.init()
      } else {
        document.body.scrollTop = this.$store.state.scrHeight
        document.documentElement.scrollTop = this.$store.state.scrHeight
        this.$store.dispatch('setRePage', true)
      }
    },
    deactivated () {
      this.$store.dispatch('setLoading', {visible: false})
    },
    components: {
      HeaderTop,
      MainStock,
      SimilarList,
      TopBar,
      DownLoad,
      todaySimilar
    },
    methods: {
      init () {
        if (CommonUtil.getUrlParam('url') || this.$route.query.url) {
          this.isShare = true
          this.getShareData()
          TDAPP.onEvent('004020', '', {userCode: '', stockCode: this.market + this.stockCode})
          TDAPP.send()
        } else {
          let strN = this.$route.query.stockName || CommonUtil.getUrlParam('stockName')// let strN = '益丰药房'
          let strC = this.$route.query.stockCode || CommonUtil.getUrlParam('stockCode')// let strC = 'SH600000'
          if (strN) this.stockName = strN
          if (strC) {
            this.market = strC.substring(0, 2)
            this.stockCode = strC.substring(2, strC.length)
            this.marketCode = CommonUtil.getMarketCode(strC.substring(0, 2))
          }
          if (CommonUtil.isEmpty(this.$route.query.similarNum) || CommonUtil.isEmpty(this.$route.query.upNum) || CommonUtil.isEmpty(this.$route.query.downNum)) {
            this.fetchUpDown()
          } else {
            this.similarNum = Number(this.$route.query.similarNum)
            this.upNum = Number(this.$route.query.upNum)
            this.downNum = Number(this.$route.query.downNum)
          }

          this.guessed = false
          this.showTodaySimi = false
          this.isError = false
          this.isShare = false
          this.mainStock = null
          this.simiList = []
          this.fetchData(10, 0) // 取模板股票和10只相似股票
          TDAPP.onEvent('004007', '', {userCode: '', stockCode: strN})
          TDAPP.send()
        }
      },
      fetchData (num, start) {
        this.$store.dispatch('setLoading', {visible: true})
        let arg = {
          stockCode: this.stockCode,
          marketCode: this.marketCode,
          reqNum: num,
          preDateNum: 0,
          postDateNum: 30,
          simiRankStart: start
        }
        RemoteDAO.callUC12005211(arg).then(res => {
          // 若没有相似股票，显示今日最相似K线画面
          this.isError = false
          if (res.data.body.length < 2 && start === 0) {
            this.showTodaySimi = true
            this.$store.dispatch('setLoading', {visible: false})
            this.setShareData() // 存储分享数据
            return
          }
          let data = jsonSKLine(res.data.body)
          let mainStock = {stockName: '', kData: [], lineData: [], timeData1: [], timeData2: ['', ''], max: 100, min: 0}
          let simiList = []
          for (let list of data) {
            let listData = list.K_LINE_JSON_CONTENT
            // 处理出模板股票的配置
            if (Number(listData.SIMI_RANK) === 0) {
              listData.K_LIST.forEach(function (item, index) {
                if (item.OPEN_PRICE === item.CLOSE_PRICE && index > 0) { // 处理：开盘收盘相等，但比前一个交易日价高仍显示绿色的情况
                  if (item.CLOSE_PRICE >= listData.K_LIST[index - 1].CLOSE_PRICE) {
                    item.CLOSE_PRICE = item.CLOSE_PRICE + 0.000001
                  }
                }
                if (item.DATE_TYPE === 'PAT') {
                  mainStock.kData.push([item.OPEN_PRICE, item.CLOSE_PRICE, item.MIN_PRICE, item.MAX_PRICE])
                  mainStock.timeData1.push(CommonUtil.formatDateSlash(item.TRADEDATE))
                }
              })
              mainStock.stockName = listData.STOCK_NAME_PAT
              this.mainStock = mainStock
              this.stockName = listData.STOCK_NAME_PAT
              this.stockCode = listData.STOCK_CODE_PAT
              this.patClosePriceLast = mainStock.kData[mainStock.kData.length - 1][1]
            }
            // 处理出相似股票的配置列表
            if (Number(listData.SIMI_RANK) > 0) {
              let simiStock = {priceChgs: [], kData1: [], kData2: [], timeData1: [], timeData2: [], max: 100, min: 0}
              listData.K_LIST.forEach(function (item, index) {
                if (item.OPEN_PRICE === item.CLOSE_PRICE && index > 0) { // 处理：开盘收盘相等，但比前一个交易日价高仍显示绿色的情况
                  if (item.CLOSE_PRICE >= listData.K_LIST[index - 1].CLOSE_PRICE) {
                    item.CLOSE_PRICE = item.CLOSE_PRICE + 0.000001
                  }
                }
                if (item.DATE_TYPE === 'PAT') {
                  simiStock.kData1.push([item.OPEN_PRICE, item.CLOSE_PRICE, item.MIN_PRICE, item.MAX_PRICE])
                  simiStock.timeData1.push(CommonUtil.formatDateSlash(item.TRADEDATE))
                } else if (item.DATE_TYPE === 'POST') {
                  simiStock.kData2.push([item.OPEN_PRICE, item.CLOSE_PRICE, item.MIN_PRICE, item.MAX_PRICE])
                  simiStock.timeData2.push(CommonUtil.formatDateSlash(item.TRADEDATE))
                  simiStock.priceChgs.push(item.PRICE_CHG)
                }
              })
              let nums = CommonUtil.compute(simiStock.kData1.concat(simiStock.kData2))
              simiStock.max = nums.max
              simiStock.min = nums.min
              simiStock.stockName = listData.STOCK_NAME
              simiStock.stockCode = listData.STOCK_CODE
              simiStock.market = CommonUtil.getMarketName(listData.MARKET_CODE)
              simiStock.marketCode = listData.MARKET_CODE
              simiStock.similarity = CommonUtil.toFixed(listData.SIMILARITY * 100, 2)
              simiList.push(simiStock)
            }
          }
          this.simiList = simiList
          this.$store.dispatch('setLoading', {visible: false})
          // 相似股票相似区间后30天涨幅值 二维数组
          let arr = []
          for (let stock of this.simiList) {
            arr.push(stock.priceChgs)
          }
          this.getTrend(arr, this.patClosePriceLast) // 获取后续走势
          this.getMaxMin() // 等比例展示11条k线图
          this.guessed = true
          this.setShareData() // 存储分享数据
        }, error => {
          this.isError = true
          this.$store.dispatch('setLoading', {visible: false})
          this.$store.dispatch('setTip', {text: error.message})
        }).catch(e => {
          console.error(e)
        })
      },
      fetchUpDown () {
        let args = {
          stockCode: this.stockCode,
          marketCode: this.marketCode,
          reqNum: 2,
          dateNum: 30,
          threshold: 0.9
        }
        RemoteDAO.callUC12005212(args).then(res => {
          let data = res.data.body
          if (data.length > 0) {
            this.similarNum = Number(data[0].NUM_SIMILAR)
            this.upNum = Number(data[0].UP_NUM)
            this.downNum = Number(data[0].DOWN_NUM)
            // 存储分享数据
            let shareData = JSON.parse(localStorage.getItem('stock')) || {}
            shareData.similarNum = this.similarNum
            shareData.upNum = this.upNum
            shareData.downNum = this.downNum
            localStorage.setItem('stock', JSON.stringify(shareData))
          }
        }, error => {
          this.$store.dispatch('setTip', {text: error.message})
        }).catch((e) => {
          console.error(e)
        })
      },
      reFetchData () {
        this.mainStock = null
        this.simiList = []
        this.fetchData(10, 0) // 取模板股票和10只相似股票
        this.fetchUpDown()
      },
      getTrend (arr, closePrice) { // 算后续走势
        let patClosePrices = [] // 模板股票后续30天每天的预测收盘价
        let priceChgMs = [] // 模板股票后续30天每天的预测涨幅值
        // 行列置换(考虑到第二维数组的长度不一样的情况）
        let newArr = Array(Math.max.apply({}, arr.map(e => e.length)))
        for (let i = 0; i < newArr.length; i++) {
          newArr[i] = ''
        }
        let columnArr = newArr.map((_e, outerIndex) => arr.map((e, innerIndex) => e[outerIndex]).filter(ele => ele !== undefined))
        console.log('columnArr:', columnArr)

        // 计算arr每列的平均数
        for (let column of columnArr) {
          let avg = column.reduce((total, num) => { return total + num }) / column.length
          priceChgMs.push(avg)
        }
        console.log('priceChgMs:', priceChgMs)

        // 计算模板股票后续30天预测的每天收盘价
        for (let priceChgM of priceChgMs) {
          closePrice = closePrice * (priceChgM + 1)
          patClosePrices.push(closePrice)
          this.mainStock.timeData2.unshift('')
        }
        console.log('patClosePrices:', patClosePrices)

        this.mainStock.lineData = patClosePrices
        let nums = CommonUtil.compute(this.mainStock.kData.concat(this.mainStock.lineData))
        this.mainStock.max = nums.max + 1
        this.mainStock.min = nums.min
      },
      getMaxMin () {
        let n = CommonUtil.compute(this.mainStock.kData) // 模板股票3相似区间的最高值和最低值
        let h = n.max - n.min // 模板股票相似区间 + 后续趋势 k线容器高度
        let tbr = (this.mainStock.max - n.max) / h // 模板股票相似区间上方空档高度，与K线高度 比值 top-blank-rate
        let bbr = (n.min - this.mainStock.min) / h // 模板股票相似区间下方空档高度，与K线高度 比值  bottom-blank-rate

        for (let simiStock of this.simiList) {
          let num = CommonUtil.compute(simiStock.kData1) // 模板股票30内数据
          let height = num.max - num.min // 相似股票相似区间 + 后续区间 数据最高离最低距离
          let tbrEmp = (simiStock.max - num.max) / height // 相似股票相似区间上方空档高度，与K线高度 比值 top-blank-rate
          let bbrEmp = (num.min - simiStock.min) / height // 相似股票相似区间下方空档高度，与K线高度 比值  bottom-blank-rate
          if (tbrEmp > tbr) {
            tbr = tbrEmp
          }
          if (bbrEmp > bbr) {
            bbr = bbrEmp
          }
        }

        for (let simiStock of this.simiList) {
          let num = CommonUtil.compute(simiStock.kData1) // 模板股票30内数据
          let height = num.max - num.min // 模板股票30内K线数据最高离最低距离
          simiStock.max = num.max + height * tbr
          simiStock.min = num.min - height * bbr
        }

        this.mainStock.max = n.max + h * tbr
        this.mainStock.min = n.min - h * bbr
      },
      toStock (stockCode) {
        if (this.isShare) {
          this.$store.dispatch('setTip', {text: '下载君弘获取股票实时行情吧'})
        } else {
          window.location.href = '@min=' + stockCode
        }
      },
      toWaring (po) {
        let tdId = ''
        if (po === 1 && !this.isShare) {
          tdId = '004012'
        } else if (po === 2 && !this.isShare) {
          tdId = '004013'
        } else if (po === 1 && this.isShare) {
          tdId = '004026'
        } else if (po === 2 && this.isShare) {
          tdId = '004027'
        }
        TDAPP.onEvent(tdId, '', {userCode: '', stockCode: this.market + this.stockCode})
        TDAPP.send()
        this.$router.push('/warning')
      },
      toFuture () {
        this.$router.push('/futureTheory')
      },
      setShareData () {
        let shareTitle = ''
        if (this.simiList.length > 0) {
          shareTitle = this.stockName + '和' + this.simiList[0].stockName + '的相似度竟然有百分之' + this.simiList[0].similarity + ',快来猜猜Ta的后市吧'
        } else {
          shareTitle = '今日未找到与' + this.stockName + 'K线相似的个股,去看看今日之最吧！'
        }
        let data = JSON.parse(localStorage.getItem('stock')) || {}
        data.shareTitle = shareTitle
        data.showTodaySimi = this.showTodaySimi
        data.isError = this.isError
        data.stockName = this.stockName
        data.stockCode = this.stockCode
        data.market = this.market
        data.stock = this.market + this.stockCode
        data.similarNum = this.similarNum
        data.upNum = this.upNum
        data.downNum = this.downNum
        data.mainStock = this.mainStock
        data.simiList = this.simiList
        localStorage.setItem('stock', JSON.stringify(data))
      },
      getShareData () {
        this.$store.dispatch('setLoading', {visible: true})
        jquery.ajax({
          url: CommonUtil.getUrlParam('url') || this.$route.query.url,
          jsonp: 'callback',
          dataType: 'jsonp',
          jsonpCallback: 'niurenshare',
          success: (data) => {
            console.log('xskx/stock-shareData:', data)
            this.showTodaySimi = data.showTodaySimi
            this.isError = data.isError
            this.stockName = data.stockName
            this.stockCode = data.stockCode
            this.market = data.market
            this.similarNum = data.similarNum
            this.upNum = data.upNum
            this.downNum = data.downNum
            this.mainStock = data.mainStock
            this.simiList = data.simiList
            this.guessed = true
            document.title = this.stockName + ' ' + this.stockCode
            this.$store.dispatch('setLoading', {visible: false})
            // 微信分享
            let title = data.shareTitle
            let content = '大数据智能精准匹配，海量数据帮你来找相似K线。快来找找和你的自选相似的股票吧！'
            let icon = 'http://dl.app.gtja.com/zixun/images/plus300.png'
            window.weixinShare(title, content, icon, window.location.href)
          },
          error: (err) => {
            this.$store.dispatch('setLoading', {visible: false})
            console.error(err)
          }
        })
      }
    }
  }
</script>

<style lang="less" rel="stylesheet/less" scoped>
  #stock-page {
    margin-top: 88px;
  }

  #stock-page.isShare {
    margin-top:0;
    .fixed-top{
      top:0;
    }
  }

  #stock-page.error {
    position: absolute;
    background: #fff !important;
  }

  .main-blank {
    width: 100%;
    height: 424px;
    background: #fff !important;
  }
  .fixed-top{
    position: fixed;
    top:88px;
    width: 100%;
    z-index: 999;
  }
  .chart-note {
    width: 100%;
    height: 60px;
    display: flex;
    font-size: 24px;
    background: #212138;
    /*background: -webkit-linear-gradient(left, #f0F0F0 48.5%, #ddd 50%, #fff 50%, #fff 0);*/
    div {
      flex: 1;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
      color: #fff;
    }
    div:first-child {
      background: none;
      span{
        width: 100%;
        border-right: 1px solid #2e2e46;
      }
    }
    div:last-child {
      background: none;
      display: flex;
      justify-content: center;
      align-items: center;
      span{
        line-height: 28px;
      }
      i{
        line-height: 28px;
        font-size: 28px;
        font-weight: bold;
        margin-left: 4px;
        color: #bac9d8;
        margin-left: 10px;
      }
    }
  }

  .risk-remind {
    height: 178px;
    text-align: center;
    font-size: 24px;
    color: #999999;
    padding: 74px 0;
    background-color: #f0f0f0;
    span {
      color: #309fea;
      font-size: 22px;
      text-decoration: underline;
    }
  }

  .risk-remind.packup {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
  }

  .nodata {
    width: 100%;
    margin-bottom: 10px;
    text-align: center;
    border-bottom: 1px solid #dddddd;
    padding: 120px 0 30px;
    background: #fff;
    .nodata-img {
      width: 230px;
      margin-top: 35px;
    }
    .nodata-text {
      width: 100%;
      color: #999999;
      margin-top: 29px;
      font-size: 24px;
      line-height: 24px;
    }
  }

  .error {
    width: 100%;
    background: #fff;
    .error-img {
      margin-top: 163px;
      width: 130px;
    }
    .error-text {
      margin-top: 20px;
      font-size: 24px;
      line-height: 24px;
      color: #999999
    }
    .error-btn {
      margin: 50px auto;
      width: 240px;
      height: 68px;
      border-radius: 6px;
      color: #fff;
      background: #4aa1ff;
      font-size: 32px;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
</style>
